home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / macros / macros.c next >
Encoding:
C/C++ Source or Header  |  1995-01-21  |  10.3 KB  |  527 lines

  1. /*
  2. *    macros.c
  3. *     by Gaige B. Paulsen
  4. *****************************************************************
  5. *    NCSA Telnet for the Macintosh                                *
  6. *                                                                *
  7. *    National Center for Supercomputing Applications                *
  8. *    Software Development Group                                    *
  9. *    152 Computing Applications Building                            *
  10. *    605 E. Springfield Ave.                                        *
  11. *    Champaign, IL  61820                                        *
  12. *                                                                *
  13. *    Copyright (c) 1986-1994,                                    *
  14. *    Board of Trustees of the University of Illinois                *
  15. *****************************************************************
  16. *    7/92    Moved here from event.c and maclook.c by JMB
  17. *    11/94    Rewritten to use handle based macros JMB
  18. */
  19.  
  20. #ifdef MPW
  21. #pragma segment Macros
  22. #endif
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <ctype.h>
  27.  
  28. #include "TelnetHeader.h"
  29. #include "dialog_resrcdefs.h"
  30. #include "general_resrcdefs.h"
  31. #include "network.proto.h"                /* For netwrite proto */
  32. #include "wind.h"                /* For WindRec definition */
  33. #include "DlogUtils.proto.h"
  34. #include "parse.proto.h"
  35. #include "event.proto.h"
  36.  
  37. #include "vsdata.h"
  38. #include "vsinterf.proto.h"
  39.  
  40. #include "macros.proto.h"
  41.  
  42. #include "Sets.proto.h" //for CStringToFile
  43.  
  44. /* Macro Defines */
  45. #define MACRO_IP        0xff    /* Send IP number here */
  46. #define MACRO_LINES        0xfe    /* Send # of lines here */
  47. #define    MACRO_MAX_LEN    256        // Maximum macro length
  48.  
  49. extern Cursor *theCursors[];
  50.  
  51. Handle    gMacros[10];
  52.  
  53. void    MACROSunload(void) {}
  54.  
  55. void    initmacros( void)
  56. {
  57.     short i;
  58.  
  59.     for (i=0; i<10 ; i++) {
  60.         gMacros[i] = nil;
  61.         }
  62. }
  63.  
  64. void    setmacro(short n, char *s)            /* Set macro number <n> to the value of s */
  65. {
  66.     unsigned char    *p;
  67.     short    num, pos, escape;
  68.     short    len;
  69.     
  70.     if (n<0  || n>9)
  71.         return;
  72.  
  73.     // Restrict the maximum length of macros to MACRO_MAX_LEN bytes
  74.     len = strlen(s)+1;
  75.     if (len > (MACRO_MAX_LEN - 1)) {
  76.         len = MACRO_MAX_LEN;
  77.         s[MACRO_MAX_LEN - 1] = 0;
  78.         }
  79.     
  80.     // If this is an empty string, remove whatever storage might have been used previously
  81.     // by this macro.
  82.     if (len == 1) {
  83.         if (gMacros[n] != nil) {
  84.             DisposeHandle(gMacros[n]);
  85.             gMacros[n] = nil;
  86.             }
  87.         return;
  88.         }
  89.         
  90.     // If neccessary, create storage for the macro
  91.     if (gMacros[n] == nil) {
  92.         gMacros[n] = NewHandle(len);
  93.         if (gMacros[n] == nil) {        // Memory error
  94.             return;
  95.             }
  96.         }
  97.  
  98.     // Adjust the handle to the proper size (may be making an existing macro longer)
  99.     SetHandleSize(gMacros[n], len);
  100.     if (MemError() != noErr) {
  101.         return;
  102.         }
  103.     
  104.     HLock(gMacros[n]);
  105.     p = (unsigned char *)*gMacros[n];
  106.  
  107.     num = 0;
  108.     pos = 0;
  109.     escape = 0;
  110.     
  111.     while ( *s) {
  112.         if (escape) {
  113.             escape = 0;
  114.             switch (*s) {
  115.                 case 'i':
  116.                     if ( pos >0) {
  117.                         *p++=num;
  118.                         *p++=*s;
  119.                         pos=0;
  120.                         }
  121.                     *p++=MACRO_IP;
  122.                     break;
  123.                 case '#':
  124.                     if ( pos >0) {
  125.                         *p++=num;
  126.                         *p++=*s;
  127.                         pos=0;
  128.                         }
  129.                     *p++=MACRO_LINES;
  130.                     break;
  131.                 case 'n':
  132.                     if ( pos >0) {
  133.                         *p++=num;
  134.                         *p++=*s;
  135.                         pos=0;
  136.                         }
  137.                     *p++='\012';
  138.                     break;
  139.                 case 'r':
  140.                     if ( pos >0) {
  141.                         *p++=num;
  142.                         *p++=*s;
  143.                         pos=0;
  144.                         }
  145.                     *p++='\015';
  146.                     break;
  147.                 case 't':
  148.                     if ( pos >0) {
  149.                         *p++=num;
  150.                         *p++=*s;
  151.                         pos=0;
  152.                         }
  153.                     *p++='\t';
  154.                     break;
  155.                 case '"':
  156.                     if ( pos >0) {
  157.                         *p++=num;
  158.                         *p++=*s;
  159.                         pos=0;
  160.                         }
  161.                     *p++='\"';
  162.                     break;
  163.  
  164.                         
  165.                 case '\\':
  166.                     if ( pos >0) {
  167.                         *p++=num;
  168.                         escape=1;
  169.                         pos=0;
  170.                         num=0;
  171.                         }
  172.                     else
  173.                         *p++='\\';
  174.                     break;
  175.                 default:
  176.                     if (*s <='9' && *s >='0' && pos <3) {
  177.                         num= num*8+( *s -'0');
  178.                         pos++;
  179.                         escape=1;
  180.                         }
  181.                     else {
  182.                         if (pos ==0 && num==0) {
  183.                             *p++='\\';
  184.                             *p++=*s;
  185.                             }
  186.                         else {
  187.                             *p++=num;
  188.                             pos= 0;
  189.                             s--;            /* back up the buffer. */
  190.                             }
  191.                         }
  192.                     break;
  193.                 }
  194.             }
  195.         else {
  196.             if (*s=='\\') {
  197.                 num=0;
  198.                 pos=0;
  199.                 escape=1;
  200.                 }
  201.             else
  202.                 *p++=*s;
  203.             }
  204.         s++;
  205.         }
  206.  
  207.     if (pos >0) *p++=num;
  208.     
  209.     *p=0;
  210.     
  211.     // The resultant macro may be shorter than the input string due to escaped characters.
  212.     // So, recalculate the length of the macro and resize than handle if neccessary.
  213.     len = strlen(*gMacros[n])+1;
  214.     
  215.     HUnlock(gMacros[n]);
  216.     SetHandleSize(gMacros[n], len);
  217. } /* setmacro */
  218.  
  219. short    sendmacro(struct WindRec *tw, short n)                /* send macro number n */
  220. {
  221.     char            temp[20];
  222.     unsigned char    *mp, *first;
  223.     unsigned char    myipnum[4];
  224.     
  225.     // Invalid number
  226.     if (n<0 || n>9) {
  227.         return -1;
  228.         }
  229.     
  230.     // Empty macro, so do nothing
  231.     if (gMacros[n] == nil) {
  232.         return 0;
  233.         }
  234.     
  235.     HLock(gMacros[n]);
  236.     mp = (unsigned char *)*gMacros[n];
  237.     first = mp;
  238.     
  239.     netgetip(myipnum);
  240.  
  241.     while ( *mp) {
  242.         if (*mp==MACRO_IP) {
  243.             SendStringAsIfTyped(tw, (char *)first, mp-first);
  244.             sprintf(temp,"%d.%d.%d.%d", myipnum[0], myipnum[1], myipnum[2], myipnum[3]);
  245.             SendStringAsIfTyped(tw, temp, strlen(temp));
  246.             first = mp+1;
  247.             }
  248.         else if ( *mp==MACRO_LINES) {
  249.             SendStringAsIfTyped(tw, (char *)first, mp-first);
  250.             sprintf(temp,"%d", VSgetlines(tw->vs));
  251.             SendStringAsIfTyped(tw, temp, strlen(temp));
  252.             first = mp+1;
  253.             }
  254.  
  255.         mp++;
  256.         }
  257.  
  258.     SendStringAsIfTyped(tw, (char *)first, mp-first);
  259.  
  260.     HUnlock(gMacros[n]);
  261.     return 0;
  262. }
  263.  
  264. short    getmacro(short n, char *dest, short room)
  265. {
  266.     unsigned char    *s;
  267.  
  268.     // Invalid number
  269.     if (n<0 || n>9) {
  270.         return -1;
  271.         }
  272.     
  273.     // Empty macro, so return empty string
  274.     if (gMacros[n] == nil) {
  275.         *dest = 0;
  276.         return 0;
  277.         }
  278.         
  279.     s = (unsigned char *)*gMacros[n];
  280.     
  281.     while (*s && (room >= 5)) {  // 5 = (size of \xxx) + (terminating \0)
  282.         switch( *s) {
  283.             case MACRO_IP :
  284.                 *dest++='\\';
  285.                 *dest++='i';
  286.                 room--;
  287.                 break;
  288.             case MACRO_LINES :
  289.                 *dest++='\\';
  290.                 *dest++='#';
  291.                 room--;
  292.                 break;
  293.             case '\\':
  294.                 *dest++='\\';
  295.                 *dest++='\\';
  296.                 room--;
  297.                 break;
  298.             case '\015':
  299.                 *dest++='\\';
  300.                 *dest++='r';
  301.                 room--;
  302.                 break;
  303.             case '\012':
  304.                 *dest++='\\';
  305.                 *dest++='n';
  306.                 room--;
  307.                 break;
  308.             case '\t':
  309.                 *dest++='\\';
  310.                 *dest++='t';
  311.                 room--;
  312.                 break;
  313.             default: 
  314.                 if ( isprint(*s)) 
  315.                     *dest++=*s;
  316.                 else {
  317.                     *dest++='\\';
  318.                     *dest++= (*s / 64) +'0';
  319.                     *dest++= ((*s % 64) / 8)+'0';
  320.                     *dest++= (*s % 8) +'0';
  321.                     room = room - 3;
  322.                     }
  323.                 break;
  324.             }
  325.         room--;
  326.         s++;
  327.         }
  328.  
  329.     *dest = 0;
  330.     return( 0);
  331. }
  332.  
  333. void    Macros( void)
  334. {
  335.     DialogPtr dtemp;
  336.     short dItem;
  337.     short i;
  338.     Rect dBox;
  339.     Str255 temp;
  340.     Handle MacString[10];
  341.  
  342.     SetCursor(theCursors[normcurs]);
  343.  
  344.     dtemp=GetNewMyDialog( MacroDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  345.  
  346.     for (i=0; i<10; i++) {
  347.         getmacro(i, (char *) &temp, 256);        /* BYU LSC */
  348.         c2pstr((char *)temp);                                /* BYU LSC */
  349.         GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox);
  350.         SetIText( MacString[i], temp );
  351.         }
  352.  
  353.     dItem=0;                                /* initially no hits */
  354.     while((dItem>2) || (dItem==0)) {        /* While we are in the loop */
  355.         ModalDialog(DLOGwOK_CancelUPP,&dItem);
  356.         switch(dItem) {
  357.         case (MacroExport):
  358.             for (i=0; i<10; i++) {
  359.                 GetIText( MacString[i], temp);
  360.                 p2cstr(temp);
  361.                 setmacro(i, (char *) &temp);
  362.             }
  363.             saveMacros();
  364.             break;
  365.         case (MacroImport):
  366.             loadMacros((FSSpec *) NULL);
  367.             for (i=0; i<10; i++) {
  368.                 getmacro(i, (char *) &temp, 256);        
  369.                 c2pstr((char *)temp);                                
  370.                 GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox);
  371.                 SetIText( MacString[i], temp );
  372.             }
  373.             break;
  374.         default:
  375.             if (dItem >2 && dItem <13) 
  376.             {
  377.                 i=dItem-3;
  378.                 getmacro( i, (char *) &temp, 256);            /* BYU LSC */
  379.                 c2pstr((char *)temp);
  380.                 GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox);
  381.                 SetIText( MacString[i], temp );                /* BYU LSC - Revert the mother */
  382.                 SelIText( dtemp, i+13, 0, 32767);                /* And select it... */
  383.             }    
  384.             break;
  385.         }
  386.     }
  387.         
  388.     updateCursor(1);
  389.     
  390.     if (dItem==DLOGCancel) {
  391.             DisposDialog( dtemp);
  392.             return;
  393.             }
  394.  
  395.     for (i=0; i<10; i++) {
  396.         GetIText( MacString[i], temp);
  397.         p2cstr(temp);
  398.         setmacro(i, (char *) &temp);
  399.         }
  400.  
  401.     DisposDialog( dtemp);
  402. }
  403.  
  404. void saveMacros(void)
  405. {
  406.     SFReply        whereReply;
  407.     short         refNum,exist;
  408.     FSSpec        macroFile;
  409.     long        junk;
  410.     short         i;
  411.     char        temp[256], temp2[256];
  412.     Point        where;
  413.     OSErr        err;
  414.     where.h = 100; where.v = 100;
  415.  
  416.     
  417.     SFPutFile( where, "\pSave Macros to:", "\pTelnet Macros", 0L, &whereReply);
  418.  
  419.     if (!whereReply.good)
  420.         return;
  421.  
  422.     BlockMoveData(&whereReply.fName, macroFile.name, (*whereReply.fName)+1); 
  423.     GetWDInfo(whereReply.vRefNum, ¯oFile.vRefNum, ¯oFile.parID, &junk);
  424.  
  425.     if ((err = HCreate(macroFile.vRefNum, macroFile.parID, 
  426.             macroFile.name, kNCSACreatorSignature, 'TEXT')) == dupFNErr)
  427.         exist = 1;
  428.     
  429.     err = HOpen(macroFile.vRefNum, macroFile.parID, macroFile.name, fsWrPerm, &refNum);
  430.  
  431.     if (exist) 
  432.         SetEOF(refNum, 0L);
  433.  
  434.     
  435.     for (i = 0; i < 10; i++)
  436.     {
  437.         getmacro(i, temp, sizeof(temp));            
  438.         if (*temp) 
  439.         {                                    
  440.             sprintf(temp2, "key%d = \"", i);        
  441.             CStringToFile(refNum,(unsigned char *) temp2);
  442.             CStringToFile(refNum,(unsigned char *) temp);
  443.             strcpy(temp2,"\"\015");
  444.             CStringToFile(refNum,(unsigned char *) temp2);    
  445.         }
  446.     }
  447.     FSClose(refNum);
  448.     
  449. }
  450.  
  451. void loadMacros(FSSpec *theFile)
  452. {
  453.     SFReply        sfr;
  454.     long        junk;
  455.     SFTypeList    typesok = {'TEXT'};
  456.     Point        where;
  457.     FSSpec        macros;
  458.     OSErr         err;
  459.     short         fileRef;
  460.     where.h=100;where.v=100;
  461.  
  462.     if (theFile == 0L)
  463.     {
  464.         SFGetFile( where, "\pMacros to load:", 0L, 1, typesok, 0L, &sfr);
  465.         if (!sfr.good) return;
  466.         BlockMove(&sfr.fName, macros.name, (*sfr.fName)+1); 
  467.         GetWDInfo(sfr.vRefNum, ¯os.vRefNum, ¯os.parID, &junk);
  468.         err = HOpen(macros.vRefNum, macros.parID, macros.name, fsRdPerm, &fileRef);
  469.     }
  470.     else
  471.         err = HOpen(theFile->vRefNum, theFile->parID, theFile->name, fsRdPerm, &fileRef);
  472.     
  473.     if (err != noErr)
  474.         return;    
  475.     parseMacroFile(fileRef);
  476.     FSClose(fileRef);
  477. }
  478.  
  479. void parseMacroFile(short fileRef)
  480. {
  481.     unsigned char buffer[300],*bufferPtr;
  482.     unsigned char newMacro[256], *newMacroPtr;
  483.     OSErr fileErr = noErr;
  484.     short numMacrosRead = 0;
  485.     short totalLen,i;
  486.     long count=1;
  487.  
  488.     bufferPtr = buffer; 
  489.  
  490.     for(i = 0; i < 10; i++)
  491.     {
  492.         if (gMacros[i] != NULL)
  493.             DisposHandle(gMacros[i]);
  494.     }
  495.     initmacros();  //sets all handles to null
  496.  
  497.     while ((fileErr != eofErr)&&(numMacrosRead < 10))
  498.     {
  499.         fileErr = FSRead(fileRef,&count,bufferPtr);
  500.         while((*bufferPtr != 0x0D)&&(fileErr != eofErr))    //while not CR or EOF
  501.         {
  502.         
  503.             ++bufferPtr;
  504.             fileErr = FSRead(fileRef,&count,bufferPtr);
  505.         
  506.         }
  507.         
  508.         totalLen = bufferPtr-buffer;
  509.         bufferPtr = buffer;
  510.         newMacroPtr = newMacro;
  511.         while((*bufferPtr++ != '"')&&(totalLen != 0))
  512.             --totalLen;
  513.  
  514.         while((*bufferPtr != '"')&&(totalLen != 0))
  515.         {
  516.             *newMacroPtr++ = *bufferPtr++;
  517.             --totalLen;
  518.         }        
  519.         *newMacroPtr = NULL; //make this a C string
  520.  
  521.         setmacro(numMacrosRead,(char *)newMacro);
  522.         bufferPtr = buffer;
  523.         ++numMacrosRead;
  524.     }
  525. }
  526.         
  527.